<?
define( 'FMT_DATEFR', '%d/%m/%Y' );
define( 'FMT_DATEUS', '%m/%d/%Y' );
define( 'FMT_DATEISO', '%Y%m%dT%H%M%S' );
define( 'FMT_DATELDAP', '%Y%m%d%H%M%SZ' );
define( 'FMT_DATEMYSQL', '%Y-%m-%d %H:%M:%S' );
define( 'FMT_DATERFC822', '%a, %d %b %Y %H:%M:%S' );
define( 'FMT_TIMESTAMP_DATE', '%Y%m%d' );
define( 'FMT_TIMESTAMP_TIME', '%H%M%S' );
define( 'FMT_TIME', '%H:%M' );
define( 'WDAY_SUNDAY',    0 );
define( 'WDAY_MONDAY',    1 );
define( 'WDAY_TUESDAY',   2 );
define( 'WDAY_WENESDAY',  3 );
define( 'WDAY_THURSDAY',  4 );
define( 'WDAY_FRIDAY',    5 );
define( 'WDAY_SATURDAY',  6 );
define( 'SEC_MINUTE',    60 );
define( 'SEC_HOUR',    3600 );
define( 'SEC_DAY',    86400 );

class clsDate
{
	
	var $inputday;
	var $ts;	
	var $Y;
	var $M;
	var $D;
	var $h;
	var $m;
	var $s; 
	
	/* @scope protected */
	var $change = 0; // 1 if date needs recalculation

	function clsDate($date ="" )
	{
		$ts = strtotime( $date ); 
		if( $ts ) 
		{
			$this->inputday = $date;
			$this->setTimestamp($date);
		}
		else 
		{
			$this->setTimestamp(time());
		}
	}	
	function get_Date()
	{
		 return  date("Y/m/d",strtotime($this->inputday));
	}	
	function set_Date($date)
	{
		 $this->inputday = $date;
	}	
	function addDay($date,$add_day)
	{
		 $new_date = date("Y/m/d", strtotime("$add_day days", strtotime($date)));
		 return $new_date;
	}	
	function addWeek($date,$add_week)
	{
		 $new_date = date("Y/m/d", strtotime("$add_week weeks", strtotime($date)));
		 return $new_date;
	}
	function addMonth($date,$add_month)
	{		 
		 if($date == "")
		 {
			$this->M += $add_month;
			$this->_calc();
		 }
		 else
		 {
		 	$new_date = date("Y/m/d", strtotime("$add_month months", strtotime($date)));	 
		 }
		 return $new_date;
	}	
	function addYear($date,$add_year)
	{
		 $new_date = date("Y/m/d", strtotime("$add_year years", strtotime($date)));
		 return $new_date;
	}	
	function fromDatetime( $datetime )
	{
		if( ! preg_match( "/^(\d{4})-?(\d{2})-?(\d{2})T?(\d{2}):?(\d{2}):?(\d{2})(.?)$/", $datetime, $a ) ) 
		{
			return NULL;
		}
		$obj = new Date();
		$obj->setDate( $a[1], $a[2], $a[3] );
		$obj->setTime( $a[4],$a[5], $a[6] );
		return $obj;
	}	
	function toString( $format )
	{
		return strftime( $format, $this->getTimestamp() );
	}	
	function format( $format, $timestamp )
	{
		return strftime( $format, $timestamp );
	}
	function format_MonthYear( )
	{
		$monthYear = date('F, Y',mktime(0,0,0, $this->M, $this->D, $this->Y));
		return $monthYear;
	}
	function getYear() { 
		if( $this->change ) $this->_calc();
		return $this->Y; 
	}	
	function getMonth($format = "") { 
		if( $this->change ) $this->_calc();		
		if($format != "")
			return date( $format, $this->ts );
		else
			return $this->M; 
	}
	function getDay($format = "") { 
		if( $this->change ) $this->_calc();
		if($format != "")
			return date( $format, $this->ts );
		else
			return $this->D; 
	}
	function getWeekday() { 
		if( $this->change ) $this->_calc();
		return $this->weekday; 
	}

	function getYearDay()
	{
		if( $this->change )
			$this->_calc();
		return date( "z", $this->ts );
	}

	function getHours() { 
		if( $this->change ) $this->_calc();
		return $this->h; 
	}

	function getMinutes() { 
		if( $this->change ) $this->_calc();
		return $this->m; 
	}

	function getSeconds() { 
		if( $this->change ) $this->_calc();
		return $this->s; 
	}

	function getSecondsInDay() { 
		if( $this->change ) $this->_calc();
		$ts1 = mktime( 0,0,0, $this->M, $this->D, $this->Y );
		return $this->ts - $ts1; 
	}

	// return Unix timestamp (seconds since epoch )
	function getTimestamp() { 
		if( $this->change ) $this->_calc();
		return $this->ts; 
	}
	function getWeekInYear()
	{
		return date( "W", mktime(0,0,0,$this->Y,$this->M,$this->D));	 
	}
	function getPreviousWeek()
	{
		addDays(6);
	}
	function getNextWeek()
	{
		$this->addDays(6);
	}
	function getPreviousMonth($date)
	{
		return $this->addMonth($date, -1);
	}
	function getNextMonth($date)
	{
		return $this->addMonth($date, 1);
	}
	function daysInMonth()
	{
		if( $this->change )
			$this->_calc();
		return date( "t", $this->ts );
		//cal_days_in_month(0,$month,$year);
	}
	
	function daysInYear()
	{
		if( $this->change )
			$this->_calc();
		return date( "t", $this->ts );
	}
	
	function DaysTo( $date )
	{
		if( ! is_object($date) || get_class($date) != "date" )
			return false;
		$deltats = $date->getTimestamp() - $this->getTimestamp();
		if( $deltats > 0 )
			return (int) floor( $deltats / SEC_DAY );
		else
			return (int) ceil( $deltats / SEC_DAY );
	}
	
	function compareTo( $date )
	{
		if( ! is_object($date) || get_class($date) != "date" )
			return false;	
		return $this->getTimestamp() - $date->getTimestamp();
	}
	
	function addDays( $numdays )
	{
		if($numdays != 0)
		{
			$this->D += $numdays;
			$this->_calc();
		}
	}

	
	
	function addYears( $num )
	{
		$this->Y += $num;
		$this->_calc();
	}
	
	function addHours( $num )
	{
		$this->h += $num;
		$this->_calc();
	}

	function addMinutes( $num )
	{
		$this->m += $num;
		$this->_calc();
	}
	
	function addSeconds( $num )
	{
		$this->s += $num;
		$this->_calc();
	}
			
/**************************************************** SETTERS ****/
	
	function setTimestamp( $date )
	{
		// TODO : basic validation
		
		$this->ts = strtotime( $date ); 
		$a = getdate( $this->ts );
		$this->Y = $a['year'];
		$this->M = $a['mon'];
		$this->D = $a['mday'];
		$this->h = $a['hours'];
		$this->m = $a['minutes'];
		$this->s = $a['seconds'];
		$this->weekday = $a['wday'];
		$this->change = 0;
		unset($a);
	}

	function setDate( $Y, $M, $D=1 )
	{
		$this->Y = $Y;
		$this->M = $M;
		$this->D = $D;
		$this->change = 1;
	}

	function setTime( $h, $m, $s=0 )
	{
		$this->h = $h;
		$this->m = $m;
		$this->s = $s;
		$this->change = 1;
	}
	
	function setHours( $val )
	{
		$this->h = $val;
		$this->change = 1;
	}
	
	function setMinutes( $val )
	{
		$this->m = $val;
		$this->change = 1;
	}
	
	function setSeconds( $val )
	{
		$this->s = $val;
		$this->change = 1;
	}
	
	function setYear( $val )
	{
		$this->Y = $val;
		$this->change = 1;
	}

	function setMonth( $val )
	{
		$this->M = $val;
		$this->change = 1;
	}
	
	function setDay( $val )
	{
		$this->D = $val;
		$this->change = 1;
	}

	// setWeekday( [0-6] ) 
	function setWeekday( $weekday )
	{
		$this->D += ($weekday - $this->weekday);
		$this->change = 1;
	}

	function isValid()
	{
		if( ! checkdate( $this->M, $this->D, $this->Y ) )
			return false;
		if( $this->Y < 1970 || $this->Y > 2038 )
			return false;			
		if( $this->h < 0 || $this->h > 23 || $this->m < 0 || $this->m > 59 || $this->s < 0 || $this->s > 59 )
			return false;
		return true;
	}

	/**
	 *	@protected 
	 */
	function _calc()
	{
		$this->ts = mktime( $this->h, $this->m, $this->s, $this->M, $this->D, $this->Y );
		$a = getdate( $this->ts );
		$this->Y = $a['year'];
		$this->M = $a['mon'];
		$this->D = $a['mday'];
		$this->h = $a['hours'];
		$this->m = $a['minutes'];
		$this->s = $a['seconds'];
		$this->weekday = $a['wday'];
		$this->change = 0;
	}
		
		
}

?>
